const db = require('../config/database');
const { StatusCodes } = require('http-status-codes');
const AppError = require('../utils/appError');

class Store {
  static async create({ name, address, phone, manager_id, status = 'active' }) {
    try {
      const [result] = await db.execute(
        'INSERT INTO stores (name, address, phone, manager_id, status, created_at) VALUES (?, ?, ?, ?, ?, NOW())',
        [name, address, phone, manager_id, status]
      );
      return this.findById(result.insertId);
    } catch (err) {
      throw new AppError('Failed to create store', StatusCodes.INTERNAL_SERVER_ERROR);
    }
  }

  static async findById(id) {
    try {
      const [rows] = await db.execute(
        `SELECT s.*, e.name as manager_name 
         FROM stores s 
         LEFT JOIN employees e ON s.manager_id = e.id 
         WHERE s.id = ?`,
        [id]
      );
      if (rows.length === 0) {
        throw new AppError('Store not found', StatusCodes.NOT_FOUND);
      }
      const store = rows[0];
      store.status = this.convertStatus(store.status);
      return store;
    } catch (err) {
      if (err instanceof AppError) throw err;
      throw new AppError('Failed to find store', StatusCodes.INTERNAL_SERVER_ERROR);
    }
  }

  static async findAll() {
    try {
      const [rows] = await db.execute(
        `SELECT s.*, e.name as manager_name 
         FROM stores s 
         LEFT JOIN employees e ON s.manager_id = e.id`
      );
      return rows.map(store => ({
        ...store,
        status: this.convertStatus(store.status)
      }));
    } catch (err) {
      throw new AppError('Failed to fetch stores', StatusCodes.INTERNAL_SERVER_ERROR);
    }
  }

  static async update(id, { name, address, phone, manager_id, status }) {
    try {
      const dbStatus = this.convertToDbStatus(status);
      await db.execute(
        'UPDATE stores SET name = ?, address = ?, phone = ?, manager_id = ?, status = ?, updated_at = NOW() WHERE id = ?',
        [name, address, phone, manager_id, dbStatus, id]
      );
      return this.findById(id);
    } catch (err) {
      throw new AppError('Failed to update store', StatusCodes.INTERNAL_SERVER_ERROR);
    }
  }

  static async updateStatus(id, status) {
    try {
      const dbStatus = this.convertToDbStatus(status);
      await db.execute(
        'UPDATE stores SET status = ?, updated_at = NOW() WHERE id = ?',
        [dbStatus, id]
      );
      return this.findById(id);
    } catch (err) {
      throw new AppError('Failed to update store status', StatusCodes.INTERNAL_SERVER_ERROR);
    }
  }

  static async delete(id) {
    try {
      await db.execute('DELETE FROM stores WHERE id = ?', [id]);
      return true;
    } catch (err) {
      throw new AppError('Failed to delete store', StatusCodes.INTERNAL_SERVER_ERROR);
    }
  }

  static async findByStatus(status) {
    try {
      const dbStatus = this.convertToDbStatus(status);
      const [rows] = await db.execute(
        `SELECT s.*, e.name as manager_name 
         FROM stores s 
         LEFT JOIN employees e ON s.manager_id = e.id 
         WHERE s.status = ?`,
        [dbStatus]
      );
      return rows.map(store => ({
        ...store,
        status: this.convertStatus(store.status)
      }));
    } catch (err) {
      throw new AppError('Failed to fetch stores by status', StatusCodes.INTERNAL_SERVER_ERROR);
    }
  }

  static convertStatus(dbStatus) {
    const statusMap = {
      '1': 'active',
      '0': 'inactive',
      'active': 'active',
      'inactive': 'inactive'
    };
    return statusMap[dbStatus] || 'active';
  }

  static convertToDbStatus(status) {
    const statusMap = {
      'active': '1',
      'inactive': '0'
    };
    return statusMap[status] || '1';
  }
}

module.exports = Store; 